package org.jeecg.modules.listener;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.entity.RunnerMatchPlayer;
import org.jeecg.modules.model.*;
import org.jeecg.modules.service.IRunnerMatchPlayerService;
import org.jeecg.modules.service.MatchService;
import org.jeecg.modules.service.MessageListener;
import org.jeecg.modules.service.MqttService;
import org.jeecg.modules.service.impl.MatchServiceImpl;
import org.jeecg.modules.service.impl.TopicUtil;
import org.jeecg.modules.utill.MqttUtil;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author tanxy
 * @date 2022年11月27日 22:06
 */
@Slf4j
public class DefaultMessageListener implements MessageListener {

    private MqttService mqttService;

    private RedisUtil redisUtil;

    private MatchService matchService;

    public DefaultMessageListener(MqttService mqttService,RedisUtil redisUtil) {
        this.mqttService = mqttService;
        this.redisUtil=redisUtil;
        this.matchService =SpringContextUtils.getBean(MatchServiceImpl.class);
    }

    @Override
    public void handleConnectStatus(boolean connected) {
        if (connected) {
            System.out.println("连接MQTT服务成功。");
        } else {
            System.out.println("与MQTT服务已断开。");
        }
    }

    @Override
    public void handleMessage(String topic, byte[] msg) {

        if (StringUtils.isBlank(topic) || msg == null) {
            return;
        }

        String[] arr = topic.split("/");
        if (arr.length == 0) {
            return;
        }

        String message = new String(msg);

        String suffixTopic = "/" + arr[arr.length - 1];
        if (TopicUtil.syncTimeReqTopic.endsWith(suffixTopic)) {
            handleSyncTimeMessage(message);
        } else if (TopicUtil.heartbeatTopic.endsWith(suffixTopic)) {
            handleHeartbeatMessage(message);
        } else if (TopicUtil.gameRealTimeDataTopic.endsWith(suffixTopic)) {
            handleGameRealTimeDataMessage(message);
        } else if (TopicUtil.calling.endsWith(suffixTopic)) {
            handleCallingDataMessage(message);
        }else {
            System.out.println(String.format("topic:%s message content:%s", topic, message));
        }
    }

    private void handleSyncTimeMessage(String msg) {
        System.out.println(String.format("syncTime message content:%s", msg));

        SyncTimeReq req = JSON.parseObject(msg, SyncTimeReq.class);

        System.out.println(req);

        String syncTimeRespTopic = String.format(TopicUtil.syncTimeRespTopic, req.getDeviceId());
        try {
            SyncTimeResp resp = new SyncTimeResp();
            resp.setDeviceId(req.getDeviceId());
            resp.setServiceType(req.getServiceType());
            resp.setTime(System.currentTimeMillis());

            mqttService.publish(syncTimeRespTopic, JSON.toJSONString(resp));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleHeartbeatMessage(String msg) {
        log.info(String.format("heartbeat message content:%s", msg));

        Heartbeat heartbeat = JSON.parseObject(msg, Heartbeat.class);
        if(ObjectUtil.isNotEmpty(heartbeat)){
            if(StrUtil.isNotEmpty(heartbeat.getDeviceId())){
                redisUtil.set(heartbeat.getDeviceId(), "运行",60);
            }
        }
        log.info(heartbeat.toString());
    }

    private void handleGameRealTimeDataMessage(String msg) {
        log.info(String.format("gameRealTimeData message content:%s", msg));
        List<JSONObject> list = JSON.parseObject(msg, List.class);
        if(ObjectUtil.isNotEmpty(list)){
            JSONObject jsonObject = list.get(0);
            MatchData matchData = MatchData.builder().deviceId(jsonObject.getString("deviceId")).uid(jsonObject.getString("uid"))
                    .serviceType(jsonObject.getInteger("serviceType")).time(jsonObject.getInteger("time"))
                    .build();

            IRunnerMatchPlayerService runnerMatchPlayerService = SpringContextUtils.getBean(IRunnerMatchPlayerService.class);

            QueryWrapper<RunnerMatchPlayer> wrapperRing = new QueryWrapper<>();
            wrapperRing.eq("ringcode",matchData.getUid());
            List<RunnerMatchPlayer> playerList = runnerMatchPlayerService.list(wrapperRing);

            String userId ="";
            if(!playerList.isEmpty()){
                String matchId = playerList.get(0).getMatchid();
                Map<String, String> matchMap = MqttUtil.MATCH_MAP;
                Set<String> userIds = matchMap.keySet();
                for(String userIdT:userIds){
                    String matchIdT = matchMap.get(userIdT);
                    if(matchIdT.equals(matchId)){
                        userId=userIdT;
                        break;
                    }
                }

                Integer matchType = MqttUtil.MATCH_TYPE_MAP.get(userId);
                try{

                    if(matchType==1){
                        //检录
                        matchService.calling(matchData.getUid());
                    }else if(matchType==2){
                        //比赛
                        for(JSONObject json:list){
                            //加入防重复功能
                            String uid = jsonObject.getString("uid");
                            Object uidFlag = redisUtil.get(uid);
                            if (ObjectUtil.isEmpty(uidFlag)){
                                //10s内进来的数据全部进行拦截
                                redisUtil.set(uid,1,60);
                                MatchData md = MatchData.builder().deviceId(jsonObject.getString("deviceId")).uid(uid)
                                        .serviceType(jsonObject.getInteger("serviceType")).time(jsonObject.getLong("time"))
                                        .build();
                                matchService.match(md);
                            }
                        }
                    }
                }catch (Exception e){
                    log.error("mqtt请求错误："+e.getMessage());
                }
            }
        }
    }

    public static void main(String[] args) {
        String msg="[{\"deviceId\":\"A001\",\"uid\":\"300833B2DDD9202211200370\",\"time\":1670658510224,\"serviceType\":3}]";
        List<MatchData> list = JSON.parseObject(msg, List.class);
        System.out.println(msg);
    }
    private void handleCallingDataMessage(String msg) {
        log.info(msg);
        /**
         *{
         *   "deviceId": "A001",
         *   "uid": "0111111111111111",
         *   "serviceType": 4
         * }
         */
        MatchData matchData = JSON.parseObject(msg, MatchData.class);
        matchService.calling(matchData.getUid());
    }
}
